-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement traits, impls and generic functions with trait bounds #710
Conversation
a858bdb
to
a268c9a
Compare
93c68c1
to
d0ba7c0
Compare
d0ba7c0
to
2f8a917
Compare
I just changed this back to draft because I will update it soon™ with all the remaining parts to cover |
588483d
to
48525b2
Compare
91c3387
to
f97afea
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments.
Also, the below code causes ICE.
trait Computable {
fn compute(self) -> u256;
}
struct Mac {
pub fn compute(self) -> u256 {
return 0
}
}
impl Computable for Mac {
fn compute(self) -> u256 {
return 1
}
}
contract Bar {
pub fn foo() -> u256 {
let mac: Mac = Mac()
return mac.compute()
}
pub fn foo2() -> u256 {
let mac: Mac = Mac()
return foo_computable(val: mac)
}
}
fn foo_computable<T: Computable>(val: T) -> u256 {
return val.compute()
}
thread 'main' panicked at 'should be lowered in `lower_types_in_functions`', crates/mir/src/lower/types.rs:25:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I haven't looked into this yet, but it'd be better to address this in this PR.
@@ -747,6 +772,7 @@ impl ModuleConstantId { | |||
pub enum TypeDef { | |||
Alias(TypeAliasId), | |||
Struct(StructId), | |||
Trait(TraitId), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to discuss whether traits should be regarded as a type. For our use case, it feels be better to treat trait
as an Item
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes. That's a good point. I initially made it a type because I started by ignoring generics to just support something like:
pub fn bar(val: SomeTrait) {
}
But then later I noticed that it would be better to add generics first and only support
pub fn bar<T: SomeTrait(val: T) {
}
I don't know if we ever want to support the first example (or maybe val: impl SomeTrait
as rust does) or just leave it to generics entirely. My current thinking is that we should not support the first example and leave it to generics to work with traits and hence could remove Trait
as a type and add it as its own category of Item
.
Thanks, this code should have been rejected because generics should not be supported yet outside of struct functions. Fixed it on my local machine. |
Ok, I misunderstood the cause of ICE. I wrote the test case to check what would happen when method name conflicts happen, and it caused ICE, so I wrongly suspected that function name conflict was the cause of the ICE. After modifying the test case, it causes ICE because of name conflicts this time.
↓
So we need to mangle the function name to fix the bug, I think it would be better to implement the mangling in |
f97afea
to
9ff971e
Compare
Oh, I see. I believe this is because here we are considering the fe/crates/mir/src/db/queries/function.rs Lines 84 to 86 in 9ff971e
Do you suggest to fix it here? fe/crates/codegen/src/db/queries/function.rs Lines 19 to 24 in 9ff971e
Wouldn't that mean that we let Follow up question, we could fix that by making |
Partially yes, this is one of the concrete examples. But I didn't come up with a concrete example when I reviewed it, I just felt that it may reduce too much of the amount of information that should be kept.
Yes, it would work perfectly in this case. I just thought that name mangling should be performed in the codegen phase because the mangled name is never used from another compilation pass. But yes, fixing the class perfectly works in this case.
I think the "name" of the function would differ depending on the context. What context is in your head? Currently, the "name" of the function is used in two contexts,
Now, I'm feeling that defining separate two functions for the two purposes and removing |
5ac761f
to
468e585
Compare
Thanks again for the feedback @Y-Nak I didn't feel like adding the removal of I think the only thing left from your suggestions is the removal of |
468e585
to
170460a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @cburgdorf!
we can leave that as is for now and revisit later as we extend and tune the trait support?
👍
Abstract
We want to have traits as well as generic functions with trait bounds. One of the main motivations is to properly implement
emit
on theContext
struct aspub fn emit<T: Event>(val: T) { ... }
How was it fixed?
Working example below:
fe/crates/test-files/fixtures/features/generic_functions.fe
Lines 1 to 42 in f97afea
Some notes:
FunctionId
and intoFunctionSigId
to allow traits to reuse a bunch of code that doesn't care about the body anyway.trait PartialEq { pub fn eq<T>(self, other: T); }
)SomeTrait::some_fun()